package com.kly.user.serviceImpl.traffic.homepage;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.kly.service.MemberService;
import com.kly.user.db.dao.CustomersUserDao;
import com.kly.user.db.dao.UserDao;
import com.kly.user.db.entity.CustomersUserEntity;
import com.kly.user.db.entity.IssueUserPoolEntity;
import com.kly.user.db.entity.UserEntity;
import com.kly.user.db.entity.UserPreHomepageEntity;
import com.kly.user.dto.TrafficSourceDto;
import com.kly.user.dto.vo.TrafficSourceReq;
import com.kly.user.enums.*;
import com.kly.user.eventbus.ActionEnum;
import com.kly.user.eventbus.Event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PPhomepage extends HomepageBase {

    @PostConstruct
    public void init() {
        HomepageTrafficHandler.homepageBaseMap.put(AppEnum.PP.getUserAppFlag(), this);
    }

    @Override
    public List<UserEntity> queryUsers(UserEntity currentUser, Integer recordNum, Integer lookingFor) {

        Integer filterUserType = getFilterUsertypeForRecommend(currentUser);

        String userCode = currentUser.getUserCode();
        logger.info("==queryUsers 开始 ==,当前用户:{}", userCode);
        List<UserEntity> userEntities = new ArrayList<>();
        List<String> userCodeList = new ArrayList<>();

        if (userCode.equals("1762036137478590464") || userCode.equals("1731596961893679104")) {
            userCodeList = userDao.queryIOSRecommendUsers(recordNum);
        } else {
            logger.info("==queryUsers 当前采用的策略版本 ==,version:{}", homepageNewPolicyVersion);
            Response<Boolean> response = memberService.ifMember(userCode);
            if (response.isSuccess()) {
                Boolean member = response.getData();
                List<Integer> poolNums = new ArrayList<>();
                if (member) {
                    poolNums.add(2);
                    poolNums.add(3);
                    poolNums.add(4);
                } else {
                    poolNums.add(1);
                }
                logger.info("===homeModelV3, userCode:{}, 是否会员：{}，池子：{}", userCode, member, JSONObject.toJSONString(poolNums));
                CustomersUserEntity customersUserEntity = customersUserDao.getCustomer(userCode);
                List<IssueUserPoolEntity> userCodeEntityList;
                if (customersUserEntity == null) {
                    logger.error("===homeModelV3, 找不到当前用户的客户信息,先走V2版本，userCode:{}, 是否会员：{}，池子：{}", userCode, member, JSONObject.toJSONString(poolNums));
                    userCodeEntityList = userDao.queryIssueUserPoolV2(userCode, lookingFor, poolNums, recordNum, filterUserType != null ? filterUserType : 0);
                } else {
                    //【pp-v1.1.0】自然流量-首页下发仅显示M，随机取Model，排序需要调整 1. 2个女性M，1个男性M，3个资料排序随机，男性M资料使用光后，空位补女性M 2. 不考虑自然流量的性向
                    if (isOrganic(currentUser)) {
                        poolNums.add(3);
                        List<IssueUserPoolEntity> maleIssueUserList = userDao.queryIssueUserPoolV4(userCode, customersUserEntity.getCustomerCode(), null, poolNums, recordNum, filterUserType != null ? filterUserType : 0, GenderEnum.MAN.getType());
                        List<IssueUserPoolEntity> femaleIssueUserList = userDao.queryIssueUserPoolV4(userCode, customersUserEntity.getCustomerCode(), null, poolNums, recordNum, filterUserType != null ? filterUserType : 0, GenderEnum.WOMAN.getType());
                        userCodeEntityList = concatIssueUserPoolListV2(recordNum, maleIssueUserList, femaleIssueUserList);
                    } else {
                        logger.error("===homeModelV3, 找到当前用户的客户信息，走客户隔离逻辑，userCode:{}, 是否会员：{}，池子：{}", userCode, member, JSONObject.toJSONString(poolNums));
                        userCodeEntityList = userDao.queryIssueUserPoolV3(userCode, customersUserEntity.getCustomerCode(), lookingFor, poolNums, recordNum, filterUserType != null ? filterUserType : 0);
                    }
                }

                if (CollectionUtils.isNotEmpty(userCodeEntityList)) {
                    userCodeList = userCodeEntityList.stream().map(IssueUserPoolEntity::getUserCode).collect(Collectors.toList());
                }

                logger.info("===homeModelV2, userCode:{}, 是否会员：{}，池子：{}, 返回参数:{}", userCode, member, JSONObject.toJSONString(poolNums), JSONObject.toJSONString(userCodeEntityList));

            }
        }

        updateConnectCount(userEntities, userCodeList);
        sendPush(userCode, userEntities, userCodeList);
        return userEntities;
    }

    private Integer getFilterUsertypeForRecommend(UserEntity currentUser) {
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return null;
        }

        if (resp.getData().getWhiteFlag() == 1) {
            return UserType.MODEL.getType();
        }

        // 过滤CM 如果开关关闭，一律走非自然流量策略；如果开关开启，自然流量走自然流量策略
        if (TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum())) {
            return UserType.MODEL.getType();
        }


        return null;
    }


    private boolean isOrganic(UserEntity currentUser) {
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return false;
        }

        return TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum());
    }

    private List<IssueUserPoolEntity> concatIssueUserPoolList(int recordNum, List<IssueUserPoolEntity> maleIssueUserList, List<IssueUserPoolEntity> femaleIssueUserList) {
        if (CollectionUtils.isEmpty(femaleIssueUserList)) {
            return maleIssueUserList;
        }
        int maleCount = 0;
        int femaleCount = 0;
        int maleSize = maleIssueUserList.size();
        int femaleSize = femaleIssueUserList.size();
        int turn = 1;
        List<IssueUserPoolEntity> userCodeEntityList = new ArrayList<>();
        for (int i = 0; i < recordNum; i++) {
            if ((i % 3 == 2 || turn == 0) && maleCount < maleSize) {
                userCodeEntityList.add(maleIssueUserList.get(maleCount));
                maleCount++;
                continue;
            }
            if (femaleCount < femaleSize) {
                userCodeEntityList.add(femaleIssueUserList.get(femaleCount));
                femaleCount++;
            } else {
                turn = 0;
            }
        }
        return userCodeEntityList;
    }

    /**
     * 2女1男，然后做补充
     *
     * @param recordNum
     * @param maleIssueUserList
     * @param femaleIssueUserList
     * @return
     */
    private List<IssueUserPoolEntity> concatIssueUserPoolListV2(int recordNum, List<IssueUserPoolEntity> maleIssueUserList, List<IssueUserPoolEntity> femaleIssueUserList) {
        List<IssueUserPoolEntity> userCodeEntityList = new ArrayList<>();

        int mIndex = 0;
        int fIndex = 0;
        for (int i = 0; i < recordNum; i++) {
            if (i % 3 == 2 && mIndex < maleIssueUserList.size()) {
                userCodeEntityList.add(maleIssueUserList.get(mIndex));
                mIndex++;
            } else if (fIndex < femaleIssueUserList.size()) {
                userCodeEntityList.add(femaleIssueUserList.get(fIndex));
                fIndex++;
            }
        }

        if (userCodeEntityList.size() < recordNum) {
            if (mIndex < maleIssueUserList.size()) {
                for (int i = mIndex; i < recordNum; i++) {
                    if (userCodeEntityList.size() < recordNum)
                        userCodeEntityList.add(maleIssueUserList.get(i));
                }
            }
        }

        if (userCodeEntityList.size() < recordNum) {
            if (fIndex < femaleIssueUserList.size()) {
                for (int i = fIndex; i < recordNum; i++) {
                    if (userCodeEntityList.size() < recordNum)
                        userCodeEntityList.add(femaleIssueUserList.get(i));
                }
            }
        }

        List<List<IssueUserPoolEntity>> subLists = new ArrayList<>();
        for (int i = 0; i < userCodeEntityList.size(); i += 3) {
            subLists.add(new ArrayList<>(userCodeEntityList.subList(i, Math.min(i + 3, userCodeEntityList.size()))));
        }

        for (List<IssueUserPoolEntity> subList : subLists) {
            Collections.shuffle(subList);
        }

        List<IssueUserPoolEntity> shuffledList = new ArrayList<>();
        for (List<IssueUserPoolEntity> subList : subLists) {
            shuffledList.addAll(subList);
        }

        return shuffledList;
    }

    public static void main(String[] args) {
        int a = 2 % 3;

        System.err.println(1);
    }
}
